package com.hs.service;

import com.hs.config.PageObj;
import com.hs.dao.*;
import com.hs.entity.*;
import com.hs.tool.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@Slf4j
@Service
public class TradeService {
    @Autowired
    OfferMapper offerMapper;
    @Autowired
    TradeMapper tradeMapper;
    @Autowired
    GoodMapper goodMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    TradeFlushMapper tradeFlushMapper;
    @Autowired
    UserGoodMapper userGoodMapper;
    @Autowired
    FundFlushMapper fundFlushMapper;
    public int insert(Trade trade){
        trade.setCreateTime(new Date());
        trade.setStatus(0);
        trade.setInitialAmount(trade.getAmount());
        return tradeMapper.insert(trade);
    }
    public PageObj page(Trade obj){
        int total = tradeMapper.selectTradeByConditionCount(obj);
        if(total == 0){
            return new PageObj(obj.getCurrentPage(), obj.getPageSize(),total,null);
        }
        List<Trade> list = tradeMapper.selectTradeByCondition(obj);
        return new PageObj(obj.getCurrentPage(), obj.getPageSize(),total,list);
    }
    public void deleteReptile(){
        int i = tradeMapper.deleteReptile();
        log.info("deleteReptile 删除"+i);
    }

    public void reptile() throws Exception {
        String r = HttpUtils.reptile("sh601006");
        String[] sr = r.split("=");
        log.info(sr[0]);
        log.info(sr[1]);
        String[] srr = sr[1].split(",");
        String name = srr[0];
        Double todayPlate = Double.valueOf(srr[1]);
        Double lastDayPlate = Double.valueOf(srr[2]);
        Double buyerPrice = Double.valueOf(srr[11]);
        Integer buyerAmount = Integer.valueOf(srr[10]);
        buyerAmount = buyerAmount / 100;
        buyerAmount = buyerAmount * 100;
        Double sellerPrice = Double.valueOf(srr[21]);
        Integer sellerAmount = Integer.valueOf(srr[20]);
        sellerAmount = sellerAmount / 100;
        sellerAmount = sellerAmount * 100;

        Trade trade = new Trade();
        trade.setAmount(buyerAmount);
        trade.setInitialAmount(buyerAmount);
        trade.setPrice(buyerPrice);
        trade.setType(new Integer(1).byteValue());
        trade.setStatus(0);
        trade.setCreateTime(new Date());
        trade.setUserId(0);
        trade.setUserName("网络数据");
        trade.setGoodId(1);
        if(buyerPrice != 0){
            tradeMapper.insertSelective(trade);
        }

        Trade tradeSeller = new Trade();
        tradeSeller.setAmount(sellerAmount);
        tradeSeller.setInitialAmount(sellerAmount);
        tradeSeller.setPrice(sellerPrice);
        tradeSeller.setType(new Integer(2).byteValue());
        tradeSeller.setStatus(0);
        tradeSeller.setCreateTime(new Date());
        tradeSeller.setUserId(0);
        tradeSeller.setGoodId(1);
        tradeSeller.setUserName("网络数据");
        if(buyerPrice !=0 ){
            tradeMapper.insertSelective(tradeSeller);
        }
    }

    @Transactional
    //买方为主    依次买尽
    // 以实时买方数据为标准，如果买方数据大于卖方数据，则所有买方 订单全部成交，成交量以买方订单数为标准。
    //交易公示。订单成交后，买方账户扣除对应资金，并在持有商品数量中增加，
    //卖方增加对应交易资金，并在卖方商品持仓中扣除相对应成交商品，剩余部分 继续交易。
    public void tradeSchedule() throws Exception{
        List<Good> goodList = goodMapper.selectByCondition(null);
        HashMap<String,Double> userFund = new HashMap<>();
        List<TradeFlush> tradeFlushList = new ArrayList<>();
        List<FundFlush> userFundFlushList = new ArrayList<>();
        HashMap<String,Integer> userGoodAmount = new HashMap<>();
        List<Trade> tradeListHH = new ArrayList<>();
        for(Good good : goodList){
            Trade trade = new Trade();
            trade.setGoodId(good.getId());
            trade.setType(new Integer(1).byteValue());
            trade.setStatus(0);
            trade.setOrderBy(" desc ");
            List<Trade> tradeList = tradeMapper.selectTradeByConditionForTrade(trade);
            CopyOnWriteArrayList<Trade> cb = new CopyOnWriteArrayList(tradeList.toArray());
            trade.setType(new Integer(2).byteValue());
            trade.setOrderBy("  asc ");
            List<Trade> tradeListSell = tradeMapper.selectTradeByConditionForTrade(trade);
            CopyOnWriteArrayList<Trade> cs = new CopyOnWriteArrayList(tradeListSell.toArray());

            this.tradeListCp(cb,cs,userFund,tradeFlushList,userGoodAmount,userFundFlushList);

            for(Trade b : cb){
                b.setUpdateTime(new Date());
                tradeListHH.add(b);
            }
            for(Trade s : cs){
                s.setUpdateTime(new Date());
                tradeListHH.add(s);
            }
        }


        List<User> upUserList = new ArrayList<>();
        List<UserGood> upUseGoodrList = new ArrayList<>();

        for(HashMap.Entry<String,Double> set : userFund.entrySet()){
            Integer userId  = Integer.valueOf(set.getKey());
            User user = userMapper.selectByPrimaryKey(userId);
            user.setFund(user.getFund()  + set.getValue());
            user.setUpdateTime(new Date());
            upUserList.add(user);
        }

        for(HashMap.Entry<String,Integer> set : userGoodAmount.entrySet()){
            UserGood userGood = new UserGood();
            Integer amount = set.getValue();
            Integer userId = Integer.valueOf(set.getKey().split("\\|")[0]);
            Integer goodId = Integer.valueOf(set.getKey().split("\\|")[1]);

            userGood.setGoodId(goodId);
            userGood.setUserId(userId);
            List<UserGood> userGoodList =  userGoodMapper.selectUserGoodList(userGood);//买方持有物品信息
            userGood = userGoodList != null && userGoodList.size() > 0 ? userGoodList.get(0) : null;
            userGood.setAmount(userGood.getAmount() + amount);
            upUseGoodrList.add(userGood);
        }

        for(User u : upUserList){
            if(userMapper.updateByPrimaryKey(u) == 0){
                throw  new RuntimeException("更新用户失败"+u.toString());
            }
            ;
        }
        for(UserGood userGood : upUseGoodrList){
            if( userGoodMapper.update(userGood) == 0){
                throw new RuntimeException("更新user_good失败"+ userGood.toString());
            }
        }
        for(Trade t : tradeListHH){
            if(tradeMapper.updateByPrimaryKeySelective(t) == 0){
                throw new RuntimeException("更新卖方失败");
            }
        }
        for(TradeFlush tradeFlush : tradeFlushList){
            tradeFlushMapper.insertSelective(tradeFlush);
        }
        for(FundFlush fundFlush :userFundFlushList){
            fundFlushMapper.insertSelective(fundFlush);
        }
    }

    public static void main(String[] args) {
        String [] s = "1|2".split("\\|");
        System.out.println(s);
    }
    private void tradeListCp(CopyOnWriteArrayList<Trade> cb,CopyOnWriteArrayList<Trade> cs,
                             HashMap<String,Double> userFund,List<TradeFlush> tradeFlushList,
                             HashMap<String,Integer> userGoodAmount,List<FundFlush> userFundFlushList) throws Exception {
        for(int i = 0;i < cb.size(); i++){
            Trade b = cb.get(i);
            if(b.getStatus() == 1){
                continue;
            }
            for(int j = 0;j < cs.size(); j++){
                Trade s = cs.get(j);
                if(s.getStatus() == 1){
                    continue;
                }
                if(b.getPrice() >= s.getPrice()){
                    if(b.getAmount() < s.getAmount()){
                        int amount = b.getAmount(); //成交数量
                        //交易
                        this.trade(amount,b,s,userFund,tradeFlushList,userGoodAmount,userFundFlushList);
                        //队列操作
                        b.setStatus(1);
                        s.setAmount(s.getAmount() - amount);
                        break;//终止买方循环 跳入下一个买方；  卖方大于买方的时候； 卖方继续卖
                        }else if(b.getAmount() == s.getAmount()){
                            int amount = b.getAmount(); //成交数量
                            //交易
                        this.trade(amount,b,s,userFund,tradeFlushList,userGoodAmount,userFundFlushList);
                            b.setStatus(1);
                            s.setStatus(1);
                            //终止 买方 进入下一个买方  同时去掉卖方 卖方已卖完
                            break;
                        }else if(b.getAmount() > s.getAmount()){
                            int amount = s.getAmount(); //成交数量
                            //交易
                        this.trade(amount,b,s,userFund,tradeFlushList,userGoodAmount,userFundFlushList);
                            //队列操作
                            //买方大于卖方数量   继续循环卖方 寻找合适卖家 ，同时修改买方的实时数量
                            b.setAmount(b.getAmount() - amount);
                            s.setStatus(1);
                        }
                }else{
//                        break;//继续下一个买方
                    return;  //跳出所有循环
                }
            }
        }
    }


    private void trade(int amount,Trade b,Trade s,HashMap<String,Double> userFund,
                       List<TradeFlush> tradeFlushList,HashMap<String,Integer> userGoodAmount,List<FundFlush> userFundFlushList) throws Exception{
        double price = s.getPrice();//成交价
        double money = price * amount;
        int buyerId = b.getUserId();
        int sellerId = s.getUserId();
        int goodId = b.getGoodId();

        //增减用户金额
        String key = buyerId+"";

        //买减钱
        if(userFund.get(key)!= null){
            userFund.put(key,userFund.get(key) - money);
        }else{
            userFund.put(key, - money);
        }

        FundFlush fundFlush = new FundFlush();
        fundFlush.setUserId(buyerId);
        fundFlush.setFund(- money);
        fundFlush.setCreateTime(new Date());
        fundFlush.setRemark("买入物品(key="+goodId+"):"+amount+"单位");
        userFundFlushList.add(fundFlush);

        //卖 加钱
        String sellKey = sellerId+"";
        if(userFund.get(sellKey)!= null){
            userFund.put(sellKey,userFund.get(sellKey) + money);
        }else{
            userFund.put(sellKey,+ money);
        }
        FundFlush fundFlushSell = new FundFlush();
        fundFlushSell.setUserId(sellerId);
        fundFlushSell.setFund(money);
        fundFlushSell.setCreateTime(new Date());
        fundFlushSell.setRemark("卖出物品(key="+goodId+"):"+amount+"单位");
        userFundFlushList.add(fundFlushSell);

        String buyGoodKey =  buyerId+"|"+goodId;
        String sellGoodKey =  sellerId+"|"+goodId;
        if(userGoodAmount.get(buyGoodKey)!= null){
            userGoodAmount.put(buyGoodKey,userGoodAmount.get(buyGoodKey) + amount);
        }else{
            userGoodAmount.put(buyGoodKey,amount);
        }
        if(userGoodAmount.get(sellGoodKey)!= null){
            userGoodAmount.put(sellGoodKey,userGoodAmount.get(sellGoodKey) - amount);
        }else{
            userGoodAmount.put(sellGoodKey,- amount);
        }



//        User buyer = userMapper.selectByPrimaryKey(b.getUserId());
//        buyer.setFund(buyer.getFund() - price * amount);
//        buyer.setUpdateTime(new Date());
//
//        User seller = userMapper.selectByPrimaryKey(s.getUserId());
//        seller.setFund(seller.getFund() + price * amount);
//        seller.setUpdateTime(new Date());

        //新增交易流水
        TradeFlush tradeFlush = new TradeFlush();
        tradeFlush.setGoodId(goodId);
        tradeFlush.setAmount(amount);
        tradeFlush.setPrice(price);
        tradeFlush.setBuyer(buyerId);
        tradeFlush.setSeller(sellerId);
        tradeFlush.setCreateTime(new Date());
        tradeFlushList.add(tradeFlush);
//        if(tradeFlushMapper.insertSelective(tradeFlush) == 0){
//            throw new RuntimeException("新增流水失败,流水信息"+tradeFlush.toString());
//        }else {
//            log.info("新增流水"+tradeFlush.toString());
//        }


        //更新持有物品 - （查询物品）
//        UserGood userGood = new UserGood();



//        userGood.setUserId(buyerId);
//        userGood.setGoodId(goodId);
//        List<UserGood> userGoodList =  userGoodMapper.selectUserGoodList(userGood);//买方持有物品信息
//        userGood = userGoodList != null && userGoodList.size() > 0 ? userGoodList.get(0) : null;
//
//        UserGood userGood_s = new UserGood();
//        userGood_s.setUserId(sellerId);
//        userGood_s.setGoodId(goodId);
//        List<UserGood> userGoodList_s =  userGoodMapper.selectUserGoodList(userGood_s);//卖方持有物品信息
//        userGood_s = userGoodList_s != null && userGoodList_s.size() > 0 ? userGoodList_s.get(0) : null;
//        if(userGood_s == null || userGood == null){
//            throw new RuntimeException("数据错误，没有买方或者卖方物品持有信息");
//        }
        //更新物品增减持有数量
//        userGood.setAmount(userGood.getAmount() + amount);//  买足  | 满仓
//        userGood_s.setAmount(userGood_s.getAmount() - amount); //已有的 + 卖出的

        //数据库操作
//        if(userMapper.updateByPrimaryKey(buyer) == 0 ){
//            throw new RuntimeException("更新买方金额信息失败");
//        }
//        if(userMapper.updateByPrimaryKey(seller) == 0 ){
//            throw new RuntimeException("更新卖方金额信息失败");
//        }
//        if( userGoodMapper.update(userGood) == 0){
//            throw new RuntimeException("更新买方物品信息失败");
//        }
//        if(userGoodMapper.update(userGood_s) == 0){
//            throw new RuntimeException("更新卖方物品信息失败");
//        }

    }
}
